package com.colin.util.util;


import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class HttpUtil {

    private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * 默认超时时间
     */
    private static final int DEFAULT_TIMEOUT = 60000;
    /**
     * 默认编码
     */
    private static final String DEFAULT_CHARSET = "UTF-8";
    
    public static class MyX509TrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            //信任所有证书
            return null;
        }
    }

    private static SSLSocketFactory createSSl() throws Exception {
        // 创建SSLContext对象，并使用我们指定的信任管理器初始化
        TrustManager[] tm = { new MyX509TrustManager() };
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
        sslContext.init(null, tm, new java.security.SecureRandom());
        // 从上述SSLContext对象中得到SSLSocketFactory对象
        return sslContext.getSocketFactory();
    }

    /**
     * https get 请求
     */
    public static String httpsGetRequest(String requestUrl, Map<String, String> headers) throws Exception{
        String result = "";
        StringBuffer buffer = new StringBuffer();
        HttpsURLConnection httpUrlConn = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            
            URL url = new URL(requestUrl);
            httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(createSSl());

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            httpUrlConn.setConnectTimeout(DEFAULT_TIMEOUT);
            httpUrlConn.setReadTimeout(DEFAULT_TIMEOUT);

            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod("GET");

            //设置请求头
            if(headers != null && headers.size() > 0){
                for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
                    httpUrlConn.setRequestProperty(headerEntry.getKey(), headerEntry.getValue());
                }
            }

            int code = httpUrlConn.getResponseCode();
            logger.info("http response code:" + code);

            if(code == 200){
                // 将返回的输入流转换成字符串
                inputStream = httpUrlConn.getInputStream();
            }else{
                inputStream = httpUrlConn.getErrorStream();
            }

            inputStreamReader = new InputStreamReader(inputStream, DEFAULT_CHARSET);
            bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            
            result = buffer.toString();
        } catch (ConnectException ce) {
            logger.error("https request connection timed out", ce);
        } catch (Exception e) {
            logger.error("https request error", e);
        }finally {
            if(httpUrlConn != null){
                httpUrlConn.disconnect();
            }
            if(bufferedReader != null){
                bufferedReader.close();
            }
            if(inputStreamReader != null){
                inputStreamReader.close();
            }
            if(inputStream != null){
                inputStream.close();
            }
        }
        return result;
    }

    /**
     * https post 请求
     */
    public static String httpsPostRequest(String requestUrl, String jsonParam, Map<String, String> headers) throws Exception{
        String result = "";
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(createSSl());

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            httpUrlConn.setConnectTimeout(DEFAULT_TIMEOUT);
            httpUrlConn.setReadTimeout(DEFAULT_TIMEOUT);

            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod("POST");

            //设置请求头
            httpUrlConn.setRequestProperty("Content-Type", "application/json");
            if(headers != null && headers.size() > 0){
                for (Map.Entry<String, String> headerEntry : headers.entrySet()) {
                    httpUrlConn.setRequestProperty(headerEntry.getKey(), headerEntry.getValue());
                }
            }

            // 当有数据需要提交时
            if (null != jsonParam) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(jsonParam.getBytes(DEFAULT_CHARSET));
                outputStream.close();
            }

            int code = httpUrlConn.getResponseCode();
            logger.info("http response code:" + code);

            InputStream inputStream = null;
            if(code == 200){
                // 将返回的输入流转换成字符串
                inputStream = httpUrlConn.getInputStream();
            }else{
                inputStream = httpUrlConn.getErrorStream();
            }

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, DEFAULT_CHARSET);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            result = buffer.toString();
        } catch (ConnectException ce) {
            logger.error("https request connection timed out", ce);
        } catch (Exception e) {
            logger.error("https request error", e);
        }
        return result;
    }

    public static String httpRequest(String requestUrl, String outputStr) throws Exception{
        String result = "";
        StringBuffer buffer = new StringBuffer();
        try {

            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod("POST");

            //设置请求头
            httpUrlConn.setRequestProperty("Content-Type", "application/json");

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式，防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            int code = httpUrlConn.getResponseCode();
            logger.info("http response code:" + code);

            InputStream inputStream = null;
            if(code == 200){
                // 将返回的输入流转换成字符串
                inputStream = httpUrlConn.getInputStream();
            }else{
                inputStream = httpUrlConn.getErrorStream();
            }

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;

            httpUrlConn.disconnect();
            result = buffer.toString();
        } catch (ConnectException ce) {
            logger.error("http request connection timed out", ce);
        } catch (Exception e) {
            logger.error("http request error", e);
        }
        return result;
    }

    public static String getRedirectUrl(String requestUrl) throws Exception{
        String result = "";
        try {
            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            //设置不自动重定向
            httpUrlConn.setInstanceFollowRedirects(false);

            //设置请求头,模拟手机访问
            httpUrlConn.setRequestProperty("user-agent", "Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36");

            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod("GET");

            int code = httpUrlConn.getResponseCode();

            //获取重定向地址
            if(code == 302){
                String redirectUrl = httpUrlConn.getHeaderField("Location");
                if(redirectUrl != null && !redirectUrl.isEmpty()) {
                    result  = redirectUrl;
                }
            }

            // 释放资源
            httpUrlConn.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * get请求
     * @param requestUrl 请求地址
     */
    public static String sendGet(String requestUrl, String charsetName) throws Exception{
        String result = "";
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);

            // 设置请求方式（GET/POST）
            httpUrlConn.setRequestMethod("GET");


            int code = httpUrlConn.getResponseCode();
            logger.info("http response code:" + code);

            InputStream inputStream = null;
            if(code == 200){
                // 将返回的输入流转换成字符串
                inputStream = httpUrlConn.getInputStream();
            }else{
                inputStream = httpUrlConn.getErrorStream();
            }

            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charsetName);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;

            httpUrlConn.disconnect();
            result = buffer.toString();

        } catch (ConnectException ce) {
            logger.error("http request connection timed out", ce);
        } catch (Exception e) {
            logger.error("http request error", e);
        }
        return result;

    }

    public static String upload(String host,String imgBase64,int timeout,String inputName,String filename){
        HttpURLConnection conn = null;
        DataOutputStream output = null;
        BufferedReader reader = null;
        InputStream in = null;
        String BOUNDARY = "------WebKitFormBoundar87IH92tGZK2AHZLq1";
        String contentType = "application/octet-stream";
        try{
            URL url = new URL(host);
            conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(timeout);
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "keep-alive");
            conn.setRequestProperty("User-Agent",
                    "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
            conn.setRequestProperty("Content-Type",
                    "multipart/form-data; boundary=" + BOUNDARY);

            output = new DataOutputStream(conn.getOutputStream());

            StringBuffer strBuf = new StringBuffer();
            strBuf.append("\r\n").append("--").append(BOUNDARY)
                    .append("\r\n");
            strBuf.append("Content-Disposition: form-data; name=\""
                    + inputName + "\"; filename=\"" + filename
                    + "\"\r\n");
            strBuf.append("Content-Type:" + contentType + "\r\n\r\n");
            output.write(strBuf.toString().getBytes());

            //获取图片流
            in = base64ToStream(imgBase64);
            DataInputStream inputStream = new DataInputStream(in);
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = inputStream.read(bufferOut)) != -1) {
                output.write(bufferOut, 0, bytes);
            }

            byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
            output.write(endData);

            output.flush();

            // 读取返回数据
            StringBuffer strBufRes = new StringBuffer();
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                strBufRes.append(line).append("\n");
            }
            return strBufRes.toString();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(conn != null){
                    conn.disconnect();
                }
                if(output != null){
                    output.close();
                }
                if(reader != null){
                    reader.close();
                }
                if(in != null){
                    in.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static InputStream base64ToStream(String base64) throws Exception{
        //Base64解码
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] b = decoder.decodeBuffer(base64);
        for (int i = 0; i < b.length; ++i) {
            //调整异常数据
            if(b[i] < 0) {
                b[i] += 256;
            }
        }
        return new ByteArrayInputStream(b);
    }

    public static String convertFileToBase64(String imgPath) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(imgPath);
            System.out.println("文件大小（字节）="+in.available());
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        BASE64Encoder encoder = new BASE64Encoder();
        String base64Str = encoder.encode(data);
        return base64Str;
    }

    public static void main(String[] args) {
        String host = "https://vip-apigateway.iwosai.com/api/cis/v1/files/upload";
//        String host = "https://vapi.shouqianba.com/api/cis/v1/files/upload";
        String file = "C:\\Users\\zhaolz\\Desktop\\mycard1.jpg";
        String base64 = convertFileToBase64(file);
        System.out.println(base64);
        String url = upload(host,base64,4000, "file","11");
        System.out.println(url);
    }

}
